'use strict';
// Copyright 2014 Blueant Inc. All Rights Reserved.

/**
 * @fileoverview 铁匠铺功能
 * @author sundbcn@gmail.com (sun debing)
 */

var async = require('async');
var moment = require('moment');
var _ = require('lodash');
var Code = require('../../../consts/code');
var moduleType = require('../../../consts/moduleType');
var operationType = require('../../../consts/operationType');
var PlayerManager = require('../../../libs/playerManager');
var dataApi = require('../../../libs/dataApi');
var rewardService = require('../../../services/rewardService');
var roleService = require('../../../services/roleService');
var smithyConf = require('../../../config/smithyConf.js');
var taskService = require('../../../services/taskService.js');
var vipConf = require('../../../config/vipConf.js');
var constantUtil = require('../../../util/constantUtil.js');
var buySpConf = require('../../../config/buySpConf.js');
var techType = require('../../../consts/techType.js');
var unionTechType = require('../../../consts/unionTechType.js');
var unionTechService = require('../../../services/unionTechService.js');
var buildType = require('../../../consts/buildType.js');
var buildConf = require('../../../config/buildConf.js');

module.exports = function (app) {
    return new Handler(app);
};

var Handler = function (app) {
    this.app = app;
};

/**
 * 副本精力购买
 */
Handler.prototype.buy = function (msg, session, next) {
    var role_id = session.uid;
    var smithy_energy_times = 0;
    var now_enerty = 0;

    var player_manager = new PlayerManager(role_id);
    async.waterfall(
        [
            function (cb) {
                player_manager.refreshData(cb);
            },
            function (cb) {
                player_manager.getModel(
                    ['role', 'smithy', 'build', 'bag', 'accrued'],
                    cb
                );
            },
            function (cb) {
                var role_model = player_manager.role;
                var smithy_model = player_manager.smithy;

                // 是否有购买体力次数
                var vip_buy_num = vipConf.getCanBuyEnergyMaxNum(role_model.getVip());

                if (smithy_model.getEnergyNum() >= vip_buy_num) {
                    return next(null, {
                        code: Code.SMITHY_NOT_ENERGY_NUM
                    });
                }

                // 扣除钻石
                var sub_diamond = buySpConf.getConfSmithyEnergy(smithy_model.getEnergyNum() + 1);
                if (!roleService.subDiamond(player_manager, moduleType.MDL_SMITHY, operationType.OPR_SMITHY_BUY, sub_diamond)) {
                    // 钻石够不够
                    return next(null, {
                        code: Code.USER_DIAMOND_NOT_ENOUGH
                    });
                }

                // 加入购买次数
                smithy_model.addEnergyNum();
                smithy_energy_times = smithy_model.getEnergyNum();
                var buy_energy_num = constantUtil.value('buy_energy_num');
                roleService.addSmithyEnergy(player_manager, moduleType.MDL_SMITHY, operationType.OPR_SMITHY_BUY, buy_energy_num);
                now_enerty = smithy_model.getEnergy();
                player_manager.save(cb);
            }
        ],
        function (err) {
            if (!!err) {
                console.error(err);
                return next(null, {
                    code: Code.FAIL
                });
            }
            return next(null, {
                code: Code.OK,
                result: {
                    energy_times: smithy_energy_times,
                    now_enerty: now_enerty
                }
            });
        }
    );
};

/**
 * 开始
 */
Handler.prototype.start = function (msg, session, next) {
    var role_id = session.uid;
    var smithy_id = msg.smithy_id;
    var worker_id = msg.worker_id;
    var worker_time = msg.worker_time;
    var now_worker_list = [];
    var energy = 0;

    if (!smithy_id || !worker_id || !worker_time || !smithyConf.getWorkerTime(worker_id, worker_time)) {
        return next(null, {
            code: Code.PARAM_ERROR
        });
    }

    var player_manager = new PlayerManager(role_id);
    async.waterfall(
        [
            function (cb) {
                player_manager.getModel(
                    ['role', 'smithy', 'build', 'tech', 'task', 'daily_task', 'achieve', 'sevenDayActivity', 'accrued'],
                    cb
                );
            },
            function (cb) {
                unionTechService.getUnionTechValue(player_manager, unionTechType.UNION_TECH_104, cb);
            },
            function (union_tech_value, cb) {
                var role_model = player_manager.role;
                var smithy_model = player_manager.smithy;
                var tech_model = player_manager.tech;
                var build_model = player_manager.build;

                var smithy_lv = build_model.getBuildListByType(buildType.SMITHY)[0].lv || 1;
                var smithy_build_lv_quick_time = buildConf.getBuildLvConf(buildType.SMITHY, smithy_lv).smithy_speed || 0;

                // 是否有队列可精练
                if (!smithy_model.isOk()) {
                    return next(null, {
                        code: Code.SMITHY_WORKER_NOT_ERROR
                    });
                }

                // 工人是否开放
                if (!!smithy_model.isWorkerOpenOK(worker_id)) {
                    return next(null, {
                        code: Code.SMITHY_WORKER_NOT_OPEN
                    });
                }

                // 队列是否存在
                if (!!smithy_model.isWorkerSchedule(smithy_id)) {
                    return next(null, {
                        code: Code.SMITHY_FAIL
                    });
                }

                // 扣除精力
                var cost_smithy_energy = smithyConf.getEnergy(worker_id, worker_time);
                if (!roleService.subSmithyEnergy(player_manager, moduleType.MDL_SMITHY, operationType.OPR_SMITHY_PRODUCE, cost_smithy_energy)) {
                    return next(null, {
                        code: Code.SMITHY_NOT_ENOUGH
                    });
                }

                var production_time = worker_time;
                var tech_value = 1 + tech_model.getEffByTechType(techType.LESS_SMITHY_TIME) / 100;
                var union_tech_value_gain = 1 + union_tech_value / 100;
                var sub_tech_time = parseInt(worker_time / tech_value / union_tech_value_gain / (1 + smithy_build_lv_quick_time / 100));

                // 加入队列
                smithy_model.addWorkerSchedule(smithy_id, worker_id, sub_tech_time, production_time);
                now_worker_list = smithy_model.getWorkerSchedule();

                // 铁匠铺锻造次数统计
                taskService.addSmithyForgingNum(player_manager);
                player_manager.save(cb);
            }
            ],
        function (err) {
            if (!!err) {
                console.error(err);
                return next(null, {
                    code: Code.FAIL
                });
            }
            return next(null, {
                code: Code.OK,
                result: {
                    now_worker_list: now_worker_list,
                    energy: energy
                }
            });
        }
    );
};

/**
 * 领取奖励
 */
Handler.prototype.receive = function (msg, session, next) {
    var role_id = session.uid;
    var smithy_id = msg.smithy_id;

    if (!smithy_id) {
        return next(null, {
            code: Code.PARAM_ERROR
        });
    }

    var reward_list = [];
    var range_random = 0;

    var player_manager = new PlayerManager(role_id);
    async.waterfall(
        [
            function (cb) {
                player_manager.getModel(
                    ['role', 'smithy', 'build', 'soldier', 'bag', 'accrued'],
                    cb
                );
            },
            function (cb) {
                var role_model = player_manager.role;
                var smithy_model = player_manager.smithy;

                // 是否在队列中
                if (!smithy_model.isWorkerSchedule(smithy_id).state) {
                    return next(null, {
                        code: Code.SMITHY_NOT_QUEUE
                    });
                }

                var worker_item = smithy_model.isWorkerSchedule(smithy_id).item;
                var worker_id = worker_item.worker_id;

                var production_time = worker_item.total_time;
                var smithy_max_num_conf = smithyConf.getProductionRange(worker_id, production_time);
                range_random = _.random(smithy_max_num_conf.min_num, smithy_max_num_conf.max_num);

                if (worker_item.getEndTime() > moment()) {
                    return next(null, {
                        code: Code.SMITHY_NOT_TIME
                    });
                }

                var diff_list = [];
                for (var i = 0; i < range_random; i++) {
                    var item = smithyConf.getProbabilityInfo(worker_id);
                    diff_list.push(item[0]);
                }

                // 移除队列
                smithy_model.remove(smithy_id);

                // 发放奖励
                reward_list = _contItemNum(diff_list);
                if (!reward_list) {
                    return next(null, {
                        code: Code.REWARD_ERROR
                    });
                }
                rewardService.addRewardListToRole(player_manager, reward_list, moduleType.MDL_SMITHY, operationType.OPR_SMITHY_PRODUCE);
                player_manager.save(cb);
            }
        ],
        function (err) {
            if (!!err) {
                console.error(err);
                return next(null, {
                    code: Code.FAIL
                });
            }
            return next(null, {
                code: Code.OK,
                result: {
                    reward_list: reward_list
                }
            });
        }
    );
};

/**
 * 开启工匠槽
 */
Handler.prototype.open = function (msg, session, next) {
    var role_id = session.uid;
    var smithy_id = msg.smithy_id;

    if (!smithy_id) {
        return next(null, {
            code: Code.PARAM_ERROR
        });
    }
    var smithy_list = [];
    var player_manager = new PlayerManager(role_id);
    async.waterfall(
        [
            function (cb) {
                player_manager.getModel(
                    ['role', 'smithy', 'build', 'accrued'],
                    cb
                );
            },
            function (cb) {
                var role_model = player_manager.role;
                var smithy_model = player_manager.smithy;

                // 工匠槽是否开启
                if (!smithy_model.isSmithyOpenOK(smithy_id)) {
                    return next(null, {
                        code: Code.SMITHY_WORKER_OK_OPEN
                    });
                }

                // 是否为下一级开启的工匠槽
                if (!smithy_model.isSmithyOpenOkNext(smithy_id)) {
                    return next(null, {
                        code: Code.SMITHY_NOT_NEXT
                    });
                }

                // 扣除钻石
                var sub_diamond = smithyConf.getPoint(smithy_id);
                if (!roleService.subDiamond(player_manager, moduleType.MDL_SMITHY, operationType.OPR_SMITHY_ADD_WORK, sub_diamond)) {
                    return next(null, {
                        code: Code.USER_DIAMOND_NOT_ENOUGH
                    });
                }

                // 加入工匠槽id
                smithy_model.openSmithy(smithy_id);
                var list = smithy_model.getSmithyOpenList();
                _.each(list, function (value) {
                    smithy_list.push({
                        smithy_id: value,
                        state: 1
                    });
                });

                player_manager.save(cb);
            }
        ],
        function (err) {
            if (!!err) {
                console.error(err);
                return next(null, {
                    code: Code.FAIL
                });
            }
            return next(null, {
                code: Code.OK,
                result: {
                    now_open_smithy: smithy_list
                }
            });
        }
    );
};

/**
 * 秒完单个任务
 */
Handler.prototype.direct = function (msg, session, next) {
    var role_id = session.uid;
    var smithy_id = msg.smithy_id;

    if (!smithy_id) {
        return next(null, {
            code: Code.PARAM_ERROR
        });
    }
    var now_worker_list = [];
    var player_manager = new PlayerManager(role_id);
    async.waterfall(
        [
            function (cb) {
                player_manager.getModel(
                    ['role', 'smithy', 'build', 'accrued'],
                    cb
                );
            },
            function (cb) {
                var role_model = player_manager.role;
                var smithy_model = player_manager.smithy;

                // 是否有此队列
                if (!smithy_model.isWorkerSchedule(smithy_id).state) {
                    return next(null, {
                        code: Code.SMITHY_NOT_QUEUE
                    });
                }

                // 秒队列操作
                var item = smithy_model.isWorkerSchedule(smithy_id);
                var end_time = item.item.end_time;

                if (moment() > end_time) {
                    return next(null, {
                        code: Code.SMITHY_NOT_DIRECT
                    });
                }
                var diff_time = Math.abs(moment().diff(end_time, 's'));

                // 扣除钻石
                var sub_diamond = Math.ceil(diff_time / 60 * 0.5);

                if (!roleService.subDiamond(player_manager, moduleType.MDL_SMITHY, operationType.OPR_SMITHY_CLEAR_CD, sub_diamond)) {
                    return next(null, {
                        code: Code.USER_DIAMOND_NOT_ENOUGH
                    });
                }

                // 增加延时处理秒完后  -10误差
                item.item.end_time = moment().add(-10, 's');
                now_worker_list = smithy_model.getWorkerSchedule();
                player_manager.save(cb);
            }
        ],
        function (err) {
            if (!!err) {
                console.error(err);
                return next(null, {
                    code: Code.FAIL
                });
            }
            return next(null, {
                code: Code.OK,
                result: {
                    now_worker_list: now_worker_list
                }
            });
        }
    );
};

// 统计个数（相同的累加）
var _contItemNum = function (list_all) {
    var avg_user_count = {};
    var list = [];
    _.forEach(list_all, function (item) {
        if (!avg_user_count[item.reward]) {
            avg_user_count[item.reward] = _.clone(item);
        } else {
            avg_user_count[item.reward].reward_num += +(item.reward_num);
        }
    });
    _.forEach(avg_user_count, function (value) {
        list.push(value);
    });
    return list;
};
